/**
 * 流式客户端
 * 用于处理流式数据响应（使用wx.request的onChunkReceived事件）
 * 使用策略模式处理不同数据格式
 */

/**
 * 数据解析策略接口
 */
class DataParserStrategy {
  /**
   * 解析数据
   * @param {string} text 文本数据
   * @returns {Array} 解析后的数据块数组
   */
  parse(text) {
    throw new Error('必须实现parse方法')
  }
  
  /**
   * 检查是否是结束标记
   * @param {string} data 数据
   * @returns {boolean} 是否是结束标记
   */
  isEndMarker(data) {
    throw new Error('必须实现isEndMarker方法')
  }
}

/**
 * SSE数据解析策略
 */
class SSEDataParser extends DataParserStrategy {
  parse(text) {
    return text.split('\n\n')
  }
  
  isEndMarker(data) {
    return data === '[END]'
  }
}

/**
 * JSON数据解析策略
 */
class JSONDataParser extends DataParserStrategy {
  parse(text) {
    try {
      const data = JSON.parse(text)
      return [data]
    } catch (error) {
      console.error('JSON解析失败:', error)
      return []
    }
  }
  
  isEndMarker(data) {
    return data && data.type === 'end'
  }
}

/**
 * 纯文本数据解析策略
 */
class TextDataParser extends DataParserStrategy {
  parse(text) {
    return [text]
  }
  
  isEndMarker(data) {
    return data === '[DONE]'
  }
}

/**
 * 数据解析策略工厂
 */
class ParserFactory {
  static createParser(type) {
    switch (type) {
      case 'sse':
        return new SSEDataParser()
      case 'json':
        return new JSONDataParser()
      case 'text':
        return new TextDataParser()
      default:
        return new SSEDataParser() // 默认使用SSE解析器
    }
  }
}

class StreamingClient {
  constructor(url, options = {}) {
    this.url = url
    this.options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream'
      },
      dataType: 'sse', // 数据类型：sse, json, text
      ...options
    }
    
    // 创建数据解析策略
    this.parser = ParserFactory.createParser(this.options.dataType)
    
    this.listeners = {}
    this.isClosed = false
    this.requestTask = null
    this.buffer = '' // 用于存储未完成的数据块
    this.maxBufferSize = 1024 * 1024 // 最大缓冲区大小 1MB，防止内存泄漏
  }
  
  /**
   * 添加事件监听器
   * @param {string} event 事件名称
   * @param {function} callback 回调函数
   */
  addEventListener(event, callback) {
    if (!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event].push(callback)
  }
  
  /**
   * 移除事件监听器
   * @param {string} event 事件名称
   * @param {function} callback 回调函数
   */
  removeEventListener(event, callback) {
    if (this.listeners[event]) {
      this.listeners[event] = this.listeners[event].filter(cb => cb !== callback)
    }
  }
  
  /**
   * 触发事件
   * @param {string} event 事件名称
   * @param {any} data 数据
   */
  _dispatchEvent(event, data) {
    if (this.listeners[event]) {
      this.listeners[event].forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error('流式事件处理错误:', error)
        }
      })
    }
  }
  
  /**
   * 连接到流式服务器
   */
  connect() {
    if (this.requestTask) {
      console.warn('流式客户端已经连接')
      return
    }
    
    try {
      const { method, headers, body } = this.options
      
      // 创建请求任务
      this.requestTask = uni.request({
        url: this.url,
        method: method || 'POST',
        header: headers,
        data: body,
        responseType: 'text',
        enableChunked: true, // 启用分块传输
        success: (res) => {
          // 请求成功完成
          if (!this.isClosed) {
            // 解析最后剩余的缓冲区数据
            if (this.buffer) {
              this._parseSSEData('\n\n') // 添加结束符来处理剩余数据
            }
            this._dispatchEvent('close')
          }
        },
        fail: (error) => {
          // 请求失败
          if (!this.isClosed) {
            this._dispatchEvent('error', error)
          }
        },
        complete: () => {
          // 请求完成（无论成功还是失败）
          if (this.requestTask) {
            this.requestTask = null
          }
        }
      })
      
      // 监听数据块接收事件（小程序特有）
      if (this.requestTask && this.requestTask.onChunkReceived) {
        this.requestTask.onChunkReceived((res) => {
          if (!this.isClosed) {
            // 检查缓冲区大小，防止内存泄漏
            if (this.buffer.length > this.maxBufferSize) {
              console.warn('缓冲区超过最大大小，关闭连接')
              this.close()
              return
            }
            
            // 处理接收到的数据块
            this._parseSSEData(new TextDecoder('utf-8').decode(res.chunk))
          }
        })
      }
      
      // 触发open事件
      this._dispatchEvent('open')
    } catch (error) {
      console.error('流式连接错误:', error)
      this._dispatchEvent('error', error)
    }
  }
  
  /**
   * 解析SSE格式的数据
   * @param {string} text 接收到的文本数据
   */
  _parseSSEData(text) {
    // 将新数据添加到缓冲区
    this.buffer += text
    
    // 使用策略模式解析数据
    const lines = this.parser.parse(this.buffer)
    
    // 保留最后一个不完整的数据块在缓冲区中
    this.buffer = lines.pop() || ''
    
    // 处理完整的数据块
    for (const line of lines) {
      let data = line
      // 对于SSE格式，需要提取data:部分
      if (this.options.dataType === 'sse' && line.startsWith('data:')) {
        // 提取数据部分（移除"data:"前缀并去除首尾空格）
        data = line.substring(5).trim()
      }
      
      // 检查是否是结束标记
      if (this.parser.isEndMarker(data)) {
        this._dispatchEvent('message', { data: '[END]' })
        this.close() // 完成后自动关闭连接
        return
      }
      
      // 触发message事件
      this._dispatchEvent('message', { data })
    }
  }
  
  /**
   * 关闭连接
   */
  close() {
    this.isClosed = true
    this.buffer = '' // 清空缓冲区
    
    if (this.requestTask) {
      this.requestTask.abort()
      this.requestTask = null
    }
    
    this._dispatchEvent('close')
  }
  
  /**
   * 检查连接是否已关闭
   */
  isConnectionClosed() {
    return this.isClosed
  }
}

export default StreamingClient